package com.jdrx.sw.sewage.service;

import com.alibaba.fastjson.JSONObject;
import com.bimface.exception.BimfaceException;
import com.bimface.sdk.BimfaceClient;
import com.google.common.collect.Maps;
import com.jdrx.sw.sewage.common.constant.Constant;
import com.jdrx.sw.sewage.common.enums.EDigitalTwinFileType;
import com.jdrx.sw.sewage.common.helper.HttpUtils;
import com.jdrx.sw.sewage.service.common.RedisService;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class DigitalTwinServiceImpl {
    public static final Logger logger = LoggerFactory.getLogger(DigitalTwinServiceImpl.class);

    @Value("${bimface.host}")
    private String host;
    @Value("${bimface.AppKey}")
    private String appKey;
    @Value("${bimface.AppSecret}")
    private String appSecret;
    @Autowired
    private RedisService redisService;

    /**
     * 获取viewToken 提前一分钟去获取
     */
    public String getViewToken(Long fileId, EDigitalTwinFileType fileType, String tenantId) throws BimfaceException {
        String cacheViewToken = redisService.getStr(Constant.BIM_VIEW_TOKEN + tenantId + "_" + fileId);
        if (StringUtils.isNotEmpty(cacheViewToken)) return cacheViewToken;

        String viewToken = null;
        if (EDigitalTwinFileType.FILE_ID.getKey().equals(fileType.getKey()))
            viewToken = getBimfaceClient().getViewTokenByFileId(fileId);

        if (EDigitalTwinFileType.INTEGRATE_ID.getKey().equals(fileType.getKey()))
            viewToken = getBimfaceClient().getViewTokenByIntegrateId(fileId);

        if (EDigitalTwinFileType.COMPARE_ID.getKey().equals(fileType.getKey()))
            viewToken = getBimfaceClient().getViewTokenByCompareId(fileId);

        redisService.set(Constant.BIM_VIEW_TOKEN + tenantId + "_" + fileId, viewToken, 43140l);
        return viewToken;
    }

    /**
     * 实例化 BimfaceClient
     */
    private BimfaceClient getBimfaceClient() {
        return new BimfaceClient(appKey, appSecret);
    }

    /**
     * 获取Access Token
     */
    public String apiAccessToken() throws Exception {
        String auth = "Basic " + Base64.encodeBase64String((appKey + ":" + appSecret).getBytes());
        Map<String, String> headers = Maps.newHashMap();
        headers.put("Authorization", auth);
        JSONObject jsonObject = HttpUtils.doPost(host, "/oauth2/token", headers, Maps.newHashMap(), Maps.newHashMap());

        if (!"success".equals(jsonObject.getString("code"))) return jsonObject.getString("message");
        JSONObject data = (JSONObject) jsonObject.get("data");
        return data.getString("token");
    }

    /**
     * 获取View Token
     */
    public String apiViewToken(Long fileId, EDigitalTwinFileType fileType, String tenantId) throws Exception {
        String viewToken = redisService.getStr(Constant.BIM_VIEW_TOKEN + tenantId + "_" + fileId);
        if (StringUtils.isNotEmpty(viewToken)) return viewToken;

        String cacheAccessToken = redisService.getStr(Constant.BIM_ACCESS_TOKEN + tenantId + "_" + fileId);
        if (StringUtils.isEmpty(cacheAccessToken)) {
            cacheAccessToken = apiAccessToken();
            redisService.set(Constant.BIM_ACCESS_TOKEN + tenantId + "_" + fileId, cacheAccessToken, 604740l);
        }

        Map<String, String> headers = Maps.newHashMap();
        headers.put("Authorization", "Bearer " + cacheAccessToken);
        Map<String, String> querys = Maps.newHashMap();
        if (EDigitalTwinFileType.FILE_ID.getKey().equals(fileType.getKey())) querys.put("fileId", fileId.toString());
        if (EDigitalTwinFileType.INTEGRATE_ID.getKey().equals(fileType.getKey()))
            querys.put("integrateId", fileId.toString());
        if (EDigitalTwinFileType.COMPARE_ID.getKey().equals(fileType.getKey()))
            querys.put("compareId", fileId.toString());

        JSONObject jsonObject = HttpUtils.doGet(host, "/view/token", headers, querys);
        if (!"success".equals(jsonObject.getString("code"))) return jsonObject.getString("message");
        viewToken = jsonObject.getString("data");
        redisService.set(Constant.BIM_VIEW_TOKEN + tenantId + "_" + fileId, viewToken, 43140l);
        return viewToken;
    }

    /**
     * 为文件创建bake数据包
     */
    public void addBake(Long fileId) throws Exception {
        Map<String, String> headers = Maps.newHashMap();
        headers.put("Authorization", "Bearer " + apiAccessToken());
        HttpUtils.doPut(host, "/files/" + fileId + "/bake", headers, Maps.newHashMap(), "");
    }
}
